#include <QApplication>
#include <QMainWindow>
#include <QWidget>
#include <QHBoxLayout>   // 水平布局
#include <QVBoxLayout>   // 垂直布局
#include <QGridLayout>   // 网格布局
#include <QGroupBox>     // 分组框（用于分隔布局）
#include <QPushButton>   // 按钮
#include <QLabel>        // 标签
#include <QLineEdit>     // 单行输入框
#include <QSlider>       // 滑块
#include <QSpinBox>      // 数字输入框
#include <QMessageBox>   // 消息框（交互反馈）
#include <QRadioButton>  // 单选按钮

// 主窗口类：整合三种布局管理器
class LayoutDemoWindow : public QMainWindow {
    Q_OBJECT
public:
    explicit LayoutDemoWindow(QWidget *parent = nullptr) : QMainWindow(parent) {
        setWindowTitle("Qt 布局管理器 Demo（水平+垂直+网格）");
        setMinimumSize(800, 600);  // 窗口最小尺寸

        // 1. 中心Widget（所有布局的容器）
        QWidget *centralWidget = new QWidget(this);
        setCentralWidget(centralWidget);

        // 2. 主布局：垂直布局（用于放置三个布局分区）
        QVBoxLayout *mainLayout = new QVBoxLayout(centralWidget);
        mainLayout->setSpacing(20);  // 布局内控件间距
        mainLayout->setContentsMargins(20, 20, 20, 20);  // 布局边距（上右下左）

        // 3. 1 水平布局（QHBoxLayout）分区
        addHorizontalLayoutGroup(mainLayout);

        // 3. 2 垂直布局（QVBoxLayout）分区
        addVerticalLayoutGroup(mainLayout);

        // 3. 3 网格布局（QGridLayout）分区
        addGridLayoutGroup(mainLayout);
    }

private:
    // 1. 添加水平布局分区
    void addHorizontalLayoutGroup(QVBoxLayout *mainLayout) {
        // 分组框：用于标识当前布局类型
        QGroupBox *hGroup = new QGroupBox("1. 水平布局（QHBoxLayout）：控件沿水平方向排列", this);
        hGroup->setMinimumHeight(150);

        // 水平布局对象
        QHBoxLayout *hLayout = new QHBoxLayout(hGroup);
        hLayout->setSpacing(15);  // 水平方向控件间距
        hLayout->setContentsMargins(15, 15, 15, 15);  // 布局边距

        // 向水平布局添加控件
        QLabel *label = new QLabel("输入名称：", this);
        QLineEdit *edit = new QLineEdit(this);
        edit->setPlaceholderText("请输入文本...");

        QPushButton *btn1 = new QPushButton("按钮1", this);
        QPushButton *btn2 = new QPushButton("按钮2（拉伸）", this);
        QPushButton *btn3 = new QPushButton("按钮3", this);

        // 关键：设置拉伸因子（stretch）：控件占用剩余空间的比例
        // 拉伸因子为0：控件大小固定（默认）；>0：按比例分配空间
        hLayout->addWidget(label, 0);    // 不拉伸
        hLayout->addWidget(edit, 1);     // 拉伸比例1
        hLayout->addWidget(btn1, 0);     // 不拉伸
        hLayout->addWidget(btn2, 2);     // 拉伸比例2（占比最大）
        hLayout->addWidget(btn3, 0);     // 不拉伸

        // 交互：点击按钮弹出提示
        connect(btn1, &QPushButton::clicked, this, [=]() {
            QMessageBox::information(this, "提示", "水平布局-按钮1被点击！");
        });

        // 将分组框添加到主布局
        mainLayout->addWidget(hGroup);
    }

    // 2. 添加垂直布局分区
    void addVerticalLayoutGroup(QVBoxLayout *mainLayout) {
        QGroupBox *vGroup = new QGroupBox("2. 垂直布局（QVBoxLayout）：控件沿垂直方向排列", this);
        vGroup->setMinimumHeight(150);

        // 垂直布局对象
        QVBoxLayout *vLayout = new QVBoxLayout(vGroup);
        vLayout->setSpacing(10);
        vLayout->setContentsMargins(15, 15, 15, 15);

        // 向垂直布局添加控件
        QLabel *titleLabel = new QLabel("音量调节", this);
        titleLabel->setStyleSheet("font-size: 16px; font-weight: bold;");

        // 滑块+数字框组合（水平排列，嵌套布局）
        QWidget *sliderWidget = new QWidget(this);
        QHBoxLayout *sliderHLayout = new QHBoxLayout(sliderWidget);
        sliderHLayout->setSpacing(10);

        QSlider *slider = new QSlider(Qt::Horizontal, this);
        QSpinBox *spinBox = new QSpinBox(this);
        slider->setRange(0, 100);
        spinBox->setRange(0, 100);

        // 滑块与数字框联动
        connect(slider, &QSlider::valueChanged, spinBox, &QSpinBox::setValue);
      connect(spinBox, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), slider, &QSlider::setValue);

        sliderHLayout->addWidget(slider, 1);  // 滑块拉伸
        sliderHLayout->addWidget(spinBox, 0); // 数字框固定

        QPushButton *confirmBtn = new QPushButton("确认音量", this);

        // 向垂直布局添加控件（包含嵌套的水平布局）
        vLayout->addWidget(titleLabel, 0, Qt::AlignCenter);  // 居中对齐
        vLayout->addWidget(sliderWidget, 1);                 // 拉伸（占剩余空间）
        vLayout->addWidget(confirmBtn, 0, Qt::AlignRight);   // 右对齐

        // 交互：点击确认按钮显示当前音量
        connect(confirmBtn, &QPushButton::clicked, this, [=]() {
            QMessageBox::information(this, "音量", QString("当前音量：%1").arg(slider->value()));
        });

        mainLayout->addWidget(vGroup);
    }

    // 3. 添加网格布局分区
    void addGridLayoutGroup(QVBoxLayout *mainLayout) {
        QGroupBox *gridGroup = new QGroupBox("3. 网格布局（QGridLayout）：按行列网格排列控件", this);
        gridGroup->setMinimumHeight(200);

        // 网格布局对象（行、列从0开始计数）
        QGridLayout *gridLayout = new QGridLayout(gridGroup);
        gridLayout->setSpacing(10);  // 网格间距（行、列通用）
        gridLayout->setContentsMargins(15, 15, 15, 15);
        gridLayout->setColumnStretch(0, 1);  // 第0列拉伸比例1
        gridLayout->setColumnStretch(1, 2);  // 第1列拉伸比例2
        gridLayout->setRowStretch(2, 1);     // 第2行拉伸比例1

        // 向网格布局添加控件：addWidget(控件, 行, 列, 跨行数, 跨列数)
        QLabel *nameLabel = new QLabel("姓名：", this);
        QLineEdit *nameEdit = new QLineEdit(this);

        QLabel *ageLabel = new QLabel("年龄：", this);
        QSpinBox *ageSpin = new QSpinBox(this);
        ageSpin->setRange(0, 150);

        QLabel *genderLabel = new QLabel("性别：", this);
        QWidget *genderWidget = new QWidget(this);
        QHBoxLayout *genderHLayout = new QHBoxLayout(genderWidget);
        genderHLayout->setContentsMargins(0, 0, 0, 0);  // 清除边距
        QRadioButton *maleBtn = new QRadioButton("男", this);
        QRadioButton *femaleBtn = new QRadioButton("女", this);
        maleBtn->setChecked(true);  // 默认选中男
        genderHLayout->addWidget(maleBtn);
        genderHLayout->addWidget(femaleBtn);

        QPushButton *submitBtn = new QPushButton("提交表单", this);

        // 放置控件到网格
        gridLayout->addWidget(nameLabel, 0, 0);    // 第0行第0列
        gridLayout->addWidget(nameEdit, 0, 1);     // 第0行第1列
        gridLayout->addWidget(ageLabel, 1, 0);     // 第1行第0列
        gridLayout->addWidget(ageSpin, 1, 1);      // 第1行第1列
        gridLayout->addWidget(genderLabel, 2, 0);  // 第2行第0列
        gridLayout->addWidget(genderWidget, 2, 1); // 第2行第1列
        // 提交按钮：第3行第0-1列（跨2列），居中对齐
        gridLayout->addWidget(submitBtn, 3, 0, 1, 2, Qt::AlignCenter);

        // 交互：提交表单显示信息
        connect(submitBtn, &QPushButton::clicked, this, [=]() {
            QString gender = maleBtn->isChecked() ? "男" : "女";
            QString info = QString("姓名：%1\n年龄：%2\n性别：%3")
                           .arg(nameEdit->text()).arg(ageSpin->value()).arg(gender);
            QMessageBox::information(this, "表单信息", info);
        });

        mainLayout->addWidget(gridGroup);
    }
};

// 程序入口
int main(int argc, char *argv[]) {
    QApplication app(argc, argv);

    LayoutDemoWindow window;
    window.show();

    return app.exec();
}

#include "main.moc"
